local huiyu = fk.CreateSkill{
  name = "investiture__huiyu",
  dynamic_desc = function (self, player)
    local i = #player:getTableMark(self.name)
    local des = { "investiture__huiyu_1", "investiture__huiyu_2" }
    local fst, snd = math.abs(3 * i - 1), math.abs(3 * i - 2)
    return "investiture__huiyu_inner:"..Fk:translate(des[fst])..":"..Fk:translate(des[snd])
  end,
}

Fk:loadTranslationTable{
  ["investiture__huiyu"] = "晖煜",
  [":investiture__huiyu"] = "判定阶段，你可先判定一次<a href=':floating_mine'>【浮雷】</a>，再视为使用一张雷【杀】，若前者生效，则后者额外结算一次；" ..
    "准备阶段，你可交换视为使用牌与判定的顺序，令一名其他角色获得“大雾”标记，你获得“狂风”标记，直到其中一个标记发动效果。",

  [":investiture__huiyu_inner"] = "判定阶段，你可先{1}，再{2}，若前者生效，则后者额外结算一次；" ..
    "准备阶段，你可交换视为使用牌与判定的顺序，令一名其他角色获得“大雾”标记，你获得“狂风”标记，直到其中一个标记发动效果。",

  ["investiture__huiyu_1"] = "判定一次【浮雷】",
  ["investiture__huiyu_2"] = "视为使用一张雷【杀】",

  ["#investiture__huiyu-use"] = "晖煜：可以视为使用雷【杀】，判定一次【浮雷】",
  ["#investiture__huiyu-invoke"] = "晖煜：可以交换视为使用牌与判定的顺序，令一名其他角色获得“大雾”标记",

  ["@@dawu"] = "大雾",
  ["@@kuangfeng"] = "狂风",
  [":floating_mine"] = "延时锦囊牌<br />" ..
  "<b>时机</b>：出牌阶段<br />" ..
  "<b>目标</b>：一名其他角色<br />" ..
  "<b>效果</b>：将此牌置于目标角色判定区内。其判定阶段进行判定：若结果为黑桃，其受到X点雷电伤害，然后将【浮雷】置入弃牌堆。（X为【浮雷】结算次数）",

  ["$investiture__huiyu1"] = "",
  ["$investiture__huiyu2"] = "",
  ["$investiture__huiyu3"] = "",
  ["$investiture__huiyu4"] = "",
}

---@param to ServerPlayer
---@return boolean
local function doFulei(to)
  local room = to.room
  local judge = {
    who = to,
    reason = huiyu.name,
    pattern = tostring(Exppattern{ suit = {"spade"} }),
  }
  room:judge(judge)
  local result = judge.card
  if result.suit == Card.Spade then
    room:damage{
      to = to,
      damage = 1,
      damageType = fk.ThunderDamage,
      skillName = huiyu.name,
    }
    return true
  end
  return false
end

---@param player ServerPlayer
---@param use UseCardData
---@return boolean
local function useSlash(player, use)
  local room = player.room
  room:useCard(use)
  local events = room.logic.all_game_events
  for i = #events, room.logic:getCurrentEvent().id, -1 do
    if events[i].event == GameEvent.Damage then
      local d = events[i].data ---@type DamageData
      if d.damage > 0 then
        if events[i].parent then
          local grand = events[i].parent.parent
          if grand and grand.event == GameEvent.CardEffect and grand.data.card == use.card then
            return true
          end
        end
      end
    end
  end
  return false
end

huiyu:addEffect(fk.EventPhaseStart, {
  mute = true,
  anim_type = "offensive",
  can_trigger = function (self, event, target, player, data)
    if player == target and player:hasSkill(huiyu.name) then
      if data.phase == Player.Start then
        return player:getMark(huiyu.name) == 0
      elseif data.phase == Player.Judge then
        if player:getMark(huiyu.name) == 0 then
          return true
        else
          return #Fk:cloneCard("thunder__slash"):getAvailableTargets(player, { bypass_times = true, bypass_distances = true }) > 0
        end
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if data.phase == Player.Start then
      local tos = room:askToChoosePlayers(player, {
        targets = room:getOtherPlayers(player, false),
        max_num = 1,
        min_num = 1,
        skill_name = huiyu.name,
        cancelable = true,
        prompt = "#investiture__huiyu-invoke",
      })
      if #tos == 1 then
        event:setCostData(self, tos[1])
        return true
      end
    elseif player:getMark(huiyu.name) ~= 0 then
      local use = room:askToUseVirtualCard(player, {
        name = "thunder__slash",
        skill_name = huiyu.name,
        cancelable = true,
        prompt = "#investiture__huiyu-use",
        skip = true,
      })
      if use then
        event:setCostData(self, use)
        return true
      end
    else
      return room:askToSkillInvoke(player, { skill_name = huiyu.name })
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if data.phase == Player.Start then
      room:notifySkillInvoked(player, huiyu.name, "defensive")
      player:broadcastSkillInvoke(huiyu.name, 3)
      local to = event:getCostData(self) ---@type ServerPlayer
      room:addPlayerMark(to, "@@dawu")
      room:addPlayerMark(player, "@@kuangfeng")
      room:setPlayerMark(player, huiyu.name, {to.id})
    elseif player:getMark(huiyu.name) ~= 0 then
      room:notifySkillInvoked(player, huiyu.name, "offensive")
      player:broadcastSkillInvoke(huiyu.name, math.random(1,2))
      local use = event:getCostData(self) ---@type UseCardData
      local i = 1
      if useSlash(player, use) then
        i = i + 1
      end
      for _ = 1, i do
        doFulei(player)
        if player.dead then break end
      end
    else
      local i = 1
      if doFulei(player) then
        i = i + 1
      end
      for _ = 1, i do
        room:askToUseVirtualCard(player, {
          name = "thunder__slash",
          skill_name = huiyu.name,
          cancelable = false,
        })
        if player.dead then break end
      end
    end
  end
})

---@param player ServerPlayer
local function endEffect(player)
  local room = player.room
  local target = room:getPlayerById(player:getTableMark(huiyu.name)[1])
  room:setPlayerMark(player, huiyu.name, 0)
  room:removePlayerMark(player, "@@kuangfeng")
  room:removePlayerMark(target, "@@dawu")
end

huiyu:addEffect(fk.DamageInflicted, {
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(huiyu.name) then
      return (
        target:getMark("@@dawu") > 0 and data.damageType ~= fk.ThunderDamage and
          table.contains(player:getTableMark(huiyu.name), target.id)
      ) or (
        target:getMark("@@kuangfeng") > 0 and data.damageType == fk.FireDamage and player == target
      )
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if target:getMark("@@dawu") > 0 then
      room:notifySkillInvoked(player, huiyu.name, "defensive")
      player:broadcastSkillInvoke(huiyu.name, 4)
      data:preventDamage()
    else
      room:notifySkillInvoked(player, huiyu.name, "negative")
      player:broadcastSkillInvoke(huiyu.name, 4)
      data:changeDamage(1)
    end
    endEffect(player)
  end,
})

return huiyu